home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 108 / MacAddict108.iso / Software / Internet & Communication / JunkMatcher 1.5.5.dmg / JunkMatcher.app / Contents / Resources / Engine / SimplePatterns.py < prev    next >
Encoding:
Python Source  |  2005-06-01  |  5.3 KB  |  146 lines

  1. #
  2. #  SimplePatterns.py
  3. #  JunkMatcher
  4. #
  5. #  Created by Benjamin Han on 2/1/05.
  6. #  Copyright (c) 2005 Benjamin Han. All rights reserved.
  7. #
  8.  
  9. # This program is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU General Public License
  11. # as published by the Free Software Foundation; either version 2
  12. # of the License, or (at your option) any later version.
  13.  
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. # GNU General Public License for more details.
  18.  
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22.  
  23. #!/usr/bin/env python
  24.  
  25. import string
  26.  
  27. from consts import *
  28. from utilities import *
  29.  
  30.  
  31. class SimplePatterns (object):
  32.     """A list of (persistent) patterns
  33.        -------------------------------------
  34.        fn: file name
  35.        numbered: True iff the regex matching will report the last matched index (via search())
  36.        theList: the list of dictionaries; the keys are names and the values are patterns
  37.        thePattern: the regex produced by conjoining all patterns with '|'.
  38.        """
  39.     def __init__ (self, fn, numbered = False):
  40.         self.theList = []
  41.         self.fn = fn
  42.         self.numbered = numbered
  43.         self.load()
  44.  
  45.     def load (self, ignoreCase = True):
  46.         del self.theList[:]
  47.         try:
  48.             f = openFile(self.fn)
  49.         except:
  50.             # file might not exist
  51.             self.thePattern = None
  52.             return
  53.             
  54.         # SimplePatterns file format: odd lines are patterns, even lines are comments, followed by
  55.         # ASSUMPTION: ignore the active state (everything is active)
  56.         isName = False
  57.         for line in filter(lambda l:len(l), map(string.strip, f)):
  58.             if isName:
  59.                 isName = False
  60.                 d['name'] = line[1:-3]
  61.                 d['managed'] = bool(int(line[-1]))
  62.                 self.theList.append(d)
  63.             else:
  64.                 d = {'pat':line[1:-1]}
  65.                 isName = True
  66.  
  67.         # theList is ascendingly sorted on names
  68.         self.theList.sort(lambda d1, d2: cmp(d1['name'], d2['name']))
  69.         if self.numbered:
  70.             pat = r'|'.join([r'(%s)' % d['pat'] for d in self.theList])
  71.         else:
  72.             pat = r'|'.join([r'(?:%s)' % d['pat'] for d in self.theList])
  73.  
  74.         if ignoreCase:
  75.             self.thePattern = re.compile(pat, re.IGNORECASE)
  76.         else:
  77.             self.thePattern = re.compile(pat)
  78.  
  79.     def search (self, s):
  80.         """Search in string s for any pattern in self.thePattern; returns the pattern name
  81.         if one is found, otherwise returns None.
  82.  
  83.         IMPORTANT: only use this when self.numbered == True!
  84.         """
  85.         if self.thePattern is not None:
  86.             mo = self.thePattern.search(s)
  87.             if mo:
  88.                 return self.theList[mo.lastindex - 1]['name']
  89.         return None
  90.  
  91.     def match (self, s):
  92.         """Match self.thePattern with a string s; returns True/False if a match is/is not found;
  93.         returns None if there is no pattern to begin with."""
  94.         if self.thePattern is not None:
  95.             return self.thePattern.search(s) is not None
  96.         else:
  97.             return None
  98.  
  99.     def save (self):
  100.         print >> openFile(self.fn, 'w'),\
  101.               u'%s' % '\n'.join(['"%s"\n"%s" %d' % (d['pat'], d['name'], int(d['managed'])) for d in self.theList])
  102.  
  103.     def add (self, name, pattern, managed = False):
  104.         """Returns the index of the added pattern."""
  105.         self.theList.append({'name':name, 'pat':pattern, 'managed':managed})
  106.         self.thePattern = re.compile(r'|'.join([r'(%s)' % d['pat'] for d in self.theList]))
  107.         self.save()
  108.  
  109.     def addMany (self, listOfDict):
  110.         """Add all elements from listOfDict - each element is a dict with 3 keys: 'name', 'pat',
  111.         and 'managed' (bool)."""
  112.         self.theList.extend(listOfDict)
  113.         self.thePattern = re.compile(r'|'.join([r'(%s)' % d['pat'] for d in self.theList]))
  114.         self.save()
  115.  
  116.     def remove (self, idx):
  117.         del self.theList[idx]
  118.         self.thePattern = re.compile(r'|'.join([r'(%s)' % d['pat'] for d in self.theList]))
  119.         self.save()
  120.  
  121.     def removeMany (self, removeList):
  122.         for idx in removeList: del self.theList[idx]
  123.         self.thePattern = re.compile(r'|'.join([r'(%s)' % d['pat'] for d in self.theList]))
  124.         self.save()        
  125.  
  126.     def update (self, idx, name, pattern):
  127.         d = self.theList[idx]
  128.         d['name'] = name
  129.         d['pat'] = pattern
  130.         d['managed'] = False
  131.         self.thePattern = re.compile(r'|'.join([r'(%s)' % d['pat'] for d in self.theList]))
  132.         self.save()
  133.  
  134.  
  135. if __name__ == '__main__':
  136.     emailAddressPatterns = SimplePatterns('%swhitelist' % CONF_PATH)
  137.     print '\n'.join(['%s: "%s"' % (d['name'], d['pat']) for d in emailAddressPatterns.theList])
  138.     print
  139.     
  140.     print emailAddressPatterns.search('someone@sourceforge.net')
  141.     idx = emailAddressPatterns.add('Sent from CS.CMU', '(?i)@cs\.cmu\.edu$')
  142.     print emailAddressPatterns.search('someone@cs.cmu.edu')
  143.     emailAddressPatterns.remove(idx)
  144.     print emailAddressPatterns.search('someone@cs.cmu.edu')
  145.     
  146.